class IUP
	-- Class to handle the interface system of an iup application

inherit
	ANY
	ARGUMENTS
	IUP_GET_POINTER

create {IUP_INTERFACE}
	init

feature {IUP_INTERFACE}
	
	init
		-- Init the interface system
		local
			i, r: INTEGER
			argsv: ARRAY[STRING_8]
		do
			--io.put_string("Init IUP%N")
			create objects.make(0)

			-- Set some callback pointers
			set_iup_callbacks ($Current,
									 $launch_help_cb_fn, $launch_idle_action_fidle, $launch_map_cb_fn,
									 $launch_unmap_cb_fn, $launch_destroy_cb_fn, $launch_ldestroy_cb_fn,
									 $launch_getfocus_cb_fn, $launch_killfocus_cb_fn, $launch_enterwindow_cb_fn,
									 $launch_leavewindow_cb_fn, $launch_action_fn, $launch_k_any_fni,
									 $launch_close_cb_fn, $launch_copydata_cb_fnsi, $launch_dropfiles_cb_fnsiii,
									 $launch_mdiactivate_cb_fn, $launch_move_cb_fnii, $launch_resize_cb_fnii,
									 $launch_show_cb_fni, $launch_trayclick_cb_fniii, $launch_file_cb_fnss,
									 $launch_colorupdate_cb_fn, $launch_cancel_cb_fn, $launch_tabchange_cb_fnnn,
									 $launch_tabchangepos_cb_fnii, $launch_tabclose_cb_fni, $launch_rightclick_cb_fni,
									 $launch_detached_cb_fnnii, $launch_restored_cb_fnnii, $launch_openclose_cb_fni,
									 $launch_extrabutton_cb_fnii, $launch_valuechanged_cb_fn, $launch_button_cb_fniiiis,
									 $launch_action_fnff, $launch_focus_cb_fni, $launch_motion_cb_fniis, $launch_keypress_cb_fnii,
									 $launch_scroll_cb_fniff, $launch_wheel_cb_fndiis, $launch_click_cb_fns,
									 $launch_action_fnsii, $launch_caret_cb_fniii, $launch_dblclick_cb_fnis,
									 $launch_dragdrop_cb_fniiii, $launch_dropdown_cb_fni, $launch_edit_cb_fnis,
									 $launch_multiselect_cb_fns, $launch_spin_cb_fni, $launch_action_fnis,
									 $launch_action_fni, $launch_selection_cb_fnii, $launch_multiselection_cb_fnpi,
									 $launch_multiunselection_cb_fnpi, $launch_branchopen_cb_fni, $launch_branchclose_cb_fni,
									 $launch_executeleaf_cb_fni, $launch_showrename_cb_fni, $launch_rename_cb_fnis,
									 $launch_noderemoved_cb_fns, $launch_togglevalue_cb_fnii, $launch_highlight_cb_fn,
									 $launch_open_cb_fn, $launch_menuclose_cb_fn, $launch_dragbegin_cb_fnii,
									 $launch_dragdatasize_cb_fns, $launch_dragdata_cb_fnsvi, $launch_dragend_cb_fni,
									 $launch_dropdata_cb_fnsviii, $launch_dropmotion_cb_fniis, $launch_recent_cb_fn,
									 $launch_param_cb_fniv, $launch_flat_action_fn, $launch_flat_button_cb_fniiiis,
									 $launch_flat_focus_cb_fni, $launch_flat_enterwindow_cb_fn, $launch_flat_leavewindow_cb_fn,
									 $launch_draw_cb_fniiiiiic, $launch_height_cb_fni, $launch_hspan_cb_fnii,
									 $launch_mouseclick_cb_fniiiiiis, $launch_mousemotion_cb_fniiiis, $launch_ncols_cb_fn,
									 $launch_nlines_cb_fn, $launch_scrolling_cb_fnii, $launch_vspan_cb_fnii,
									 $launch_width_cb_fni, $launch_cell_fni, $launch_extended_fni,
									 $launch_select_fnii, $launch_switch_fnii, $launch_action_fniiiis,
									 $launch_click_fniis, $launch_colresize_fni, $launch_release_fniis,
									 $launch_resizematrix_fnii, $launch_mousemove_fnii, $launch_enteritem_fnii,
									 $launch_leaveitem_fnii, $launch_scrolltop_fnii, $launch_bgcolor_fniivvv,
									 $launch_fgcolor_fniivvv, $launch_font_fnii, $launch_type_fnii,
									 $launch_dropcheck_fnii, $launch_translatevalue_fniis, $launch_togglevalue_fniii,
									 $launch_drop_fnnii, $launch_menudrop_fnnii, $launch_dropselect_fniinsii,
									 $launch_edition_fniiii, $launch_value_fnii, $launch_value_edit_fniis,
									 $launch_mark_fnii, $launch_markedit_fniii, $launch_flat_motion_cb_fniis,
									 $launch_dropshow_cb_fni, $launch_button_press_cb_fnd, $launch_button_release_cb_fnd,
									 $launch_mousemove_cb_fnd, $launch_change_cb_fnvvv, $launch_drag_cb_fnvvv)

			-- Pass arguments to IUP
			create argsv.make_filled(" ", 0, argument_count)

			i := -1

			across
			   Argument_array as ic
			loop
				i := i + 1
				argsv.put(ic.item, i)
    		end
			
			r := int_iup_open ($i, get_pointer(argsv.to_c))

			-- 1 is returned by IUP if an error occurred.
			if r.is_equal(1) then
				io.put_string("An error occurred when try to open IUP interface. %N")
			end
		end

	int_iup_open (int, p: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupOpen($int, $p);"
      end

feature {IUP_GET_PARAM}

	set_get_param (wgt: IUP_GET_PARAM)
		do
			get_param := wgt
		end

feature {ANY}

	-- Commands to init the main loop, exit the loop and close the interface 
	-- system.
			
   main_loop
	   -- Executes the user interaction until a callback returns IUP_CLOSE, 
	   -- "exit_loop" is called, or hiding the last visible dialog.
		-- If you cascade many calls to "main_loop" there must be a 
		-- "return IUP_CLOSE" or "exit_llop" call for each cascade level, hiddinh 
		-- all dialogs will close only one level. Call "main_loop_level" to 
		-- obtain the current level.
		--
		-- If "main_loop" is called without any visible dialogs and no active 
		-- timers, the application will hang and will not be possible to close the 
		-- main loop. The process will have to be interrupted by the 
		-- system.
		--
		-- When the last visible dialog is hidden the "exit_loop" function is 
		-- automatically called, causing the "main_loop" to return. To avoid that 
		-- set the global attribute LOCKLOOP=YES before hiding the last dialog.
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupMainLoop();"
      end

	main_loop_level: INTEGER
		-- Returns the current cascade level of main loop. When no calls were 
		-- done, return value is 0.
		-- You can use this function to check if "main_loop" was already 
		-- called and avoid calling it again.
		--
		-- A call to "popup" will increase one level.
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupMainLoopLevel();"
      end

	loop_step: STRING
		-- Runs one iteration of the message loop. Returns immediately 
		-- after	processing any messages or if there are no messages to process.
		--
		-- Returns: IUP_CLOSE or IUP_DEFAULT.
		--
		-- This function is useful for allowing a second message loop to be 
		-- managed by the application itself. This means that messages can be 
		-- intercepted and callbacks can be processed inside an application loop.
		--
		-- If IUP_CLOSE is returned "main" loop will not end because the 
		-- return code was already processed. If you want to end main loop 
		-- when IUP_CLOSE is returned by "loop_step" then call "exit_loop" 
		-- after "loop_step" returns.
		local
			rtn: INTEGER
		do
			rtn := int_loop_step

			if rtn.is_equal(-2) then
				Result := "IUP_DEFAULT"
			else
				Result := "IUP_CLOSE"
			end
		end

	loop_step_wait: STRING
		-- Put the system in idle until a message is processed.
		local
			rtn: INTEGER
		do
			rtn := int_loop_step_wait

			if rtn.is_equal(-2) then
				Result := "IUP_DEFAULT"
			else
				Result := "IUP_CLOSE"
			end
		end

	flush
		-- Processes all pending messages in the message queue.
		-- When you change an attribute of a certain element, the change may not 
		-- take place immediately. For this update to occur faster than usual, 
		-- call "flush" after the attribute is changed.
		--
		-- Important: A call to this function may cause other callbacks to be 
		-- processed before it returns.
		--
		-- In Motif, if the X server sent an event which is not yet in the event 
		--queue, after a call to "flush" the queue might not be empty.
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupFlush();"
      end

	exit_loop
		-- Exit current loop.
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupExitLoop();"
      end

   close
	   -- Close the interface system
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupClose();"
      end

	-- Help

	help (url: STRING): INTEGER
		-- Opens the given URL. In UNIX executes Netscape, Safari (MacOS) or 
		-- Firefox (in Linux) passing the desired URL as a parameter. In Windows 
		-- executes the shell "open" operation on the given URL.
		--
		-- In UNIX you can change the used browser setting the environment 
		-- variable IUP_HELPAPP or using the global attribute "HELPAPP".
		--
		-- It is a non synchronous operation, i.e. the function will return just 
		-- after execute the command and it will not wait for its result.
		--
		-- url: may be any kind of address accepted by the Browser, that is, it 
		-- can include 'http://', or be just a file name, etc.
		--
		-- Returns: 1 if successful, -1 if failed. In Windows can return -2 if
		-- file not found.
		do
			Result := int_help(get_pointer(url.to_c))
		end

	-- Load images

	load_images
		-- Load a pre-defined stock images for buttons and labels.
		-- See: http://webserver2.tecgraf.puc-rio.br/iup/en/iupimglib.html
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupImageLibOpen();"
      end

	load_iup_controls
		-- Allow use the additional controls, must be called after "iup_open". 
		-- Several additional controls are included in this library. These 
		-- controls are drawn by IUP using CD on a IUP_CANVAS control, and are 
		-- not native controls.
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupControlsOpen();"
      end

	-- Focus
	
	get_focus: detachable IUP_WIDGET
		-- Returns the interface element that has the keyboard focus, i.e. the 
		-- element that will receive keyboard events (or Void if no element has 
		-- the focus).
		local
			p: POINTER
		do
			p := int_get_focus

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	-- Command to handle global attributes

	set_global_attribute (name: STRING; value: STRING)
		do
			int_set_global (get_pointer(name.to_c), get_pointer(value.to_c))
		end

	get_global_attribute (name: STRING): STRING
		local
			str: STRING
		do
			create str.make_from_c(int_get_global (get_pointer(name.to_c)))
			Result := str
		end

	-- Global attribute PARENTDIALOG and ICON

	set_global_parent_dialog_widget (dlg: IUP_DIALOG)
		-- Parent dialog to be used in some predefined dialogs.
		local
			p: POINTER
			str: STRING
		do
			str := once "PARENTDIALOG"
			int_set_attribute_handle (p, get_pointer(str.to_c), dlg.widget)
		end

	set_global_icon_widget (icon: IUP_IMAGE)
		-- Icon to be used in some predefined dialogs.
		local
			p: POINTER
			str: STRING
		do
			str := once "ICON"
			int_set_attribute_handle (p, get_pointer(str.to_c), icon.widget)
		end

	-- Copy attributes

	copy_attributes(src, dst: IUP_WIDGET)
		-- Copies all hash table attributes from one element to another.
		-- Internal attributes or handle attributes are not copied.
		--
		-- src: identifier of the source element.
		--	dst: identifier of the destiny element.
		do
			int_copy_attributes(src.widget, dst.widget)
		end

	-- Global attributes: General

	set_language_english
		do
			set_global_attribute ("LANGUAGE", "ENGLISH")
		end

	set_language_spanish
		do
			set_global_attribute ("LANGUAGE", "SPANISH")
		end

	set_language_portuguese
		do
			set_global_attribute ("LANGUAGE", "PORTUGUESE")
		end

	set_language (language: STRING)
		-- Sets the language name used by some pre-defined dialogs.
		--
		-- All elements that have pre-defined texts. The native dialogs like 
		-- IUP_FILE_DIALOG will always be displayed in the system language.
		--
		-- Even if the language is not supported (meaning its pack of pre-defined 
		-- strings are not defined) the new language name will be successfully 
		-- stored so you can set your own strings and return a coherent value, 
		-- and the current defined string will not be changed.
		--
		-- Here is a list of the pre-defined string names:
		-- IUP_ERROR, IUP_ATTENTION, IUP_YES, IUP_NO, IUP_INVALIDDIR, 
		-- IUP_FILEISDIR, IUP_FILENOTEXIST, IUP_FILEOVERWRITE, IUP_CREATEFOLDER,
		-- IUP_NAMENEWFOLDER, IUP_SAVEAS, IUP_OPEN, IUP_SELECTDIR, IUP_OK,
		-- IUP_CANCEL, IUP_RETRY, IUP_APPLY, IUP_RESET, IUP_GETCOLOR, IUP_HELP,
		-- IUP_RED, IUP_GREEN, IUP_BLUE, IUP_HUE, IUP_SATURATION, IUP_INTENSITY,
		-- IUP_OPACITY, IUP_PALETTE, IUP_TRUE, IUP_FALSE, IUP_FAMILY, IUP_STYLE,
		-- IUP_SIZE, IUP_SAMPLE, IUP_ERRORFILEOPEN, IUP_ERRORFILESAVE
		do
			set_global_attribute ("LANGUAGE", language)
		end

	get_language: STRING
		do
			Result := get_global_attribute("LANGUAGE")
		end

	set_language_string (name, value: STRING)
		-- Associates a name with a string as an auxiliary method for 
		-- Internationalization of applications.
		--
		-- name: name of the string.
		-- value: string value.
		--
		-- This will store the pointer. Elements that have pre-defined texts use 
		-- this function when the current language is changed.
		--
		-- IUP will not store strings for several languages at the same time, it 
		-- will store only for the current language. When "set_language" is 
		-- called only the internal pre-defined strings are replace in the 
		-- internal database. The application must register again all its strings 
		-- for the new language.
		--
		-- If a dialog is created with string names associations and the 
		-- associations are about to be changed, then the dialog must be 
		-- destroyed before the associations are changed, then created again.
		--
		-- Associations are retrieved using the "get_language_string" feature. 
		-- But to simplify the usage of the string names associations attributes 
		-- set with regular IupSetStr* functions can use the prefix "_@" to 
		-- indicate a string name and not the actual string.
		do
			int_set_language_string(get_pointer(name.to_c), get_pointer(value.to_c))
		end

	store_language_string (name, value: STRING)
		-- Like "set_language_string" but will duplicate the string internally.
		do
			int_store_language_string(get_pointer(name.to_c), get_pointer(value.to_c))
		end

	get_language_string(name: STRING): STRING
		-- Returns a language dependent string.
		local
			str: STRING
		do
			create str.make_from_c(int_get_language_string(get_pointer(name.to_c)))
			Result := str
		end

	--set_language_pack (pack: IUP_USER)
		-- Sets a pack of associations between names and string values. 
		-- Internally will call "set_language_string" for each name in the pack.
		--
		-- After setting the pack it can be destroyed. The existent associations 
		-- will not be removed. But if the new ones have the same names, the old 
		-- ones will be replaced.
	--	do
	--		int_set_language_pack(pack.widget)
	--	end

	--remove_language_pack
		-- Remove all current associations.
	--	local
	--		p: POINTER
	--	do
	--		int_set_language_pack(p)
	--	end

	get_driver: STRING
		-- Informs the current driver being used. Two drivers are available now, 
		-- one for each platform: "GTK", "Motif" and "Win32".
		do
			Result := get_global_attribute("DRIVER")
		end

	-- Global attributes: System

	set_lock_loop_yes
		-- When the last visible dialog is closed the IupExitLoop function is 
		-- called. To avoid that call this feature before hiding the last dialog.
		do
			set_global_attribute ("LOCKLOOP", "YES")
		end

	set_lock_loop_no
		do
			set_global_attribute ("LOCKLOOP", "NO")
		end

	set_exit_loop_yes
		-- Disable the "exit_loop" function when "main_loop_level" return 1. Used 
		-- when the application runs secondary dialogs that behave as full 
		-- applications but sharing the same IUP environment,
		do
			set_global_attribute ("EXITLOOP", "YES")
		end

	set_exit_loop_no
		do
			set_global_attribute ("EXITLOOP", "NO")
		end

	set_default_precision (value: INTEGER)
		-- The default number of decimal places used in floating point output by 
		-- some controls (IUP_MATRIX and IUP_GET_PARAM). Local attributes may 
		-- overwrite the default. Default: 2.
		do
			set_global_attribute ("DEFAULTPRECISION", value.out)
		end

	get_default_precision: INTEGER
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			Result := str.to_integer
		end

	set_default_decimal_symbol_period
		do
			set_global_attribute ("DEFAULTDECIMALSYMBOL", ".")
		end

	set_default_decimal_symbol_comma
		do
			set_global_attribute ("DEFAULTDECIMALSYMBOL", ",")
		end

	is_default_decimal_symbol_period: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			if str.is_equal(".") then
				Result := True
			else
				Result := False
			end
		end

	is_default_decimal_symbol_comma: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			if str.is_equal(",") then
				Result := True
			else
				Result := False
			end
		end

	set_global_menu (state: BOOLEAN)
		-- [GTK Only] Flag indicating that GTK is using a global menu instead of 
		-- a per window menu.	
		do
			set_global_attribute ("GLOBALMENU", boolean_to_yesno(state))
		end

	-- Default attributes

	set_default_theme (name: STRING)
		do
			set_global_attribute ("DEFAULTTHEME", name)
		end

	-- System Mouse and Keyboard

	set_cursor_position (x, y: INTEGER)
		-- Controls the cursor position in absolute coordinates relative to the 
		-- origin of the main screen. The origin of the main screen is at the 
		-- upper left corner, in Windows it is affected by the position of the 
		-- Start Menu when it is at the top or left side of the screen. In GTK 
		-- and Motif also generates mouse motion messages.
		local
			str: STRING
		do
			create str.make_from_string(x.out)
	      str.append_string("x")
 	      str.append_string(y.out)
	
			set_global_attribute("CURSORPOS", str)
		end

	get_cursor_position: TUPLE[INTEGER, INTEGER]
		local
			str: STRING
		do
			str := get_global_attribute("CURSORPOS")
			
			Result := components_of (str, 'x')
		end

	get_shift_key_state: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("SHIFTKEY")

			Result := yesno_to_boolean(str)
		end

	get_control_key_state: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("CONTROLKEY")

			Result := yesno_to_boolean(str)
		end

	get_modifier_keys_state: STRING
		-- Returns the state of the keyboard modifier keys: Shift, Ctrl, Alt and 
		-- sYs(Win/Apple). In the format of 4 characters: "SCAY". When not 
		-- pressed the respective letter is replaced by a space " ". 
		do
			Result := get_global_attribute("MODKEYSTATE")
		end

	-- Key codes

	is_print_key (key: INTEGER): BOOLEAN
		-- Informs if a key can be directly used as a printable character.
		local
			rv: INTEGER
		do
			rv := int_is_print_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_x_key (key: INTEGER): BOOLEAN
		-- Informs if a given key is an extended code (ASCII code >= 128).
		local
			rv: INTEGER
		do
			rv := int_is_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end
	
	is_shift_x_key (key: INTEGER): BOOLEAN
	-- Informs if a given key is an extended code using the Shift modifier.
		local
			rv: INTEGER
		do
			rv := int_is_shift_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_ctrl_x_key (key: CHARACTER): BOOLEAN
	-- Informs if a given key is an extended code using the Ctrl modifier.
		local
			rv: INTEGER
		do
			rv := int_is_ctrl_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_alt_x_key (key: CHARACTER): BOOLEAN
		--	Informs if a given key is an extended code using the Alt modifier.
		local
			rv: INTEGER
		do
			rv := int_is_alt_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_sys_x_key (key: CHARACTER): BOOLEAN
		-- Informs if a given key is an extended code using the Sys modifier.
		-- Sys in Windows is the Windows key and in Mac is the Apple key.
		local
			rv: INTEGER
		do
			rv := int_is_sys_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	x_key_base (key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_XkeyBase ($key);"
      end

	x_key_shift (key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_XkeyShift ($key);"
      end

	x_key_ctrl (key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_XkeyCtrl ($key);"
      end

	x_key_alt (key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_XkeyAlt ($key);"
      end

	x_key_sys (key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_XkeySys ($key);"
      end

	-- Mouse buttons

	is_shift (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_shift(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_control (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_control(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_1 (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_1(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_2 (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_2(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_3 (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_3(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_4 (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_4(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_5 (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_5(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_double (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_double(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_alt (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_alt(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_sys (status: STRING): BOOLEAN
		local
			a: POINTER
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_sys(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	-- CD

	init_context_plus
		external
			"C inline use %"eiffel-iup.h%""
		alias
			"cdInitContextPlus();"
      end

	use_context_plus (status: BOOLEAN): BOOLEAN
		local
			prev: INTEGER
		do
			if status then
				prev := int_use_context_plus(1)
			else
				prev := int_use_context_plus(0)
			end

			if prev.is_equal (0) then
				Result := False
			else
				Result := True
			end
		end

feature {IUP_WIDGET, IUP_CLIPBOARD}

	-- Converts

	position_to_integer (i: STRING): INTEGER
		do
			if i.is_equal("IUP_CENTER") then
				Result := 65535
			elseif i.is_equal("IUP_LEFT") or i.is_equal("IUP_TOP") then
				Result := 65534
			elseif i.is_equal("IUP_RIGHT") or i.is_equal("IUP_BOTTOM") then
				Result := 65533
			elseif i.is_equal("IUP_MOUSEPOS") then
				Result := 65532
			elseif i.is_equal("IUP_CURRENT") then
				Result := 65531
			elseif i.is_equal("IUP_CENTERPARENT") then
				Result := 65530
			else
				Result := i.to_integer
			end
		end

	-- PopUp a dialog or menu

	popup_predefined_xy (wgt: IUP_WIDGET; x, y: STRING): STRING
		-- Displays a dialog or menu in a given position on the screen using 
		-- predefined values. However you can combine a predefined value with 
		-- an integer (as string).If there was an error returns IUP_ERROR.
		--
		-- wgt: Identifier of a dialog or a menu.
		-- x: The following predefined values can be used:
		--
		--  IUP_LEFT: Positions the dialog on the left corner of the main screen
		--  IUP_CENTER: Horizontally centralizes the dialog on the main screen
		--  IUP_RIGHT: Positions the dialog on the right corner of the main screen
		--  IUP_MOUSEPOS: Positions the dialog on the mouse position
		--  IUP_CENTERPARENT: Horizontally centralizes the dialog relative to its 
		--                    parent
		--  IUP_CURRENT: use the current position of the dialog.
		--
		-- y: The following predefined calues can be used:
		--
		-- IUP_TOP: Positions the dialog on the top of the main screen
		-- IUP_CENTER: Vertically centralizes the dialog on the main screen
		-- IUP_BOTTOM: Positions the dialog on the base of the main screen
		-- IUP_MOUSEPOS: Positions the dialog on the mouse position
		-- IUP_CENTERPARENT: Vertically centralizes the dialog relative to its 
		--                   parent
		-- IUP_CURRENT: use the current position of the dialog.
		require
			is_valid_position(x, y)
		do
			Result := popup(wgt, position_to_integer(x), position_to_integer(y))
		end

	popup (wgt: IUP_WIDGET; x, y: INTEGER): STRING
		-- Shows a widget and restricts user interaction only to the specified 
		-- element.
		--
		-- wgt: Identifier of a dialog or a menu.
		-- x: horizontal position of the top left corner of the window or menu, 
		--    relative to the origin of the main screen.
		-- y: vertical position of the top left corner of the window or menu, 
		--    relative to the origin of the main screen.
		local
			r: INTEGER
		do
			r := int_popup(wgt.widget, x, y)

			if r.is_equal(-1) then
				Result := "IUP_INVALID"
			elseif r.is_equal(0) then
				Result := "IUP_NOERROR"
			else
				Result := "IUP_ERROR"
			end
		end

	-- Commands to handle objects and callbacks

	set_widget_for_object (wgt: POINTER; eiffel_object: IUP_WIDGET)
		do
			objects.put(eiffel_object, wgt)

			set_callback (eiffel_object, "LDESTROY_CB", "NONEEDED", 1)
		end

	get_widget_for_object (wgt: POINTER): detachable IUP_WIDGET
		do
			Result := widget_for_object(wgt)
		end

	delete_widget_for_object (wgt: POINTER; eiffel_object: IUP_WIDGET)
		do
			if objects.has(wgt) then
				objects.remove(wgt)
				set_callback(eiffel_object, "LDESTROY_CB", "NONEEDED", 0)
				int_destroy(wgt)
			end
		end

	set_callback (wgt: IUP_WIDGET; name: STRING; type: STRING; operation: INTEGER)
      do
			int_set_callback (wgt.widget, get_pointer(name.to_c), get_pointer(type.to_c), operation)
      end

	set_idle_action (act: detachable FUNCTION[TUPLE, STRING])
		do
			if act /= Void then
				int_set_function (get_pointer(("IDLE_ACTION").to_c), 1)
			else
				int_set_function (get_pointer(("IDLE_ACTION").to_c), 0)
			end

			idle_action := act
		end

	-- Commands to handle the hierarchy and management
	
	iup_append (control: IUP_WIDGET; new_child: IUP_WIDGET): detachable IUP_WIDGET
	   -- Insert a new widget at the end, return the object of the 
	   -- actual parent.
		local
			p: POINTER
		do
			p := int_append(control.widget, new_child.widget)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_detach (control: IUP_WIDGET)
		-- Detaches an interface element from its parent.
		do
			int_detach(control.widget)
		end
		
	iup_insert (control: IUP_WIDGET; ref_child: IUP_WIDGET; new_child: IUP_WIDGET): detachable IUP_WIDGET
	   -- Insert a new widget before the reference widget, return the 
	   -- object of the actual parent.
		local
			p: POINTER
		do
			p := int_insert(control.widget, ref_child.widget, new_child.widget)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_reparent (child: IUP_WIDGET; new_parent: IUP_WIDGET; ref_child: IUP_WIDGET): STRING
		-- Moves an interface element from one position in the hierarchy
		-- tree to another.
		local
			r: INTEGER
		do
			r := int_reparent(child.widget, new_parent.widget, ref_child.widget)

			if r.is_equal(0) then
				Result := "IUP_NOERROR"
			else
				Result := "IUP_ERROR"
			end
		end

	iup_get_parent (child: IUP_WIDGET): detachable IUP_WIDGET
		-- Returns the parent of a control.
		local
			p: POINTER
		do
			p := int_get_parent(child.widget)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_get_child (control: IUP_WIDGET; position: INTEGER): detachable IUP_WIDGET
		-- Returns the a child of the control given its position
		-- or NULL if there is none.
		local
			p: POINTER
		do
			p := int_get_child(control.widget, position)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_get_child_pos (control: IUP_WIDGET; child: IUP_WIDGET): INTEGER
		-- Returns the position of a child of the given control.
		-- The position of the desire child starting at 0, or -1 if child 
		-- not found.
		do
			Result := int_get_child_pos(control.widget, child.widget)
		end

	iup_get_child_count (control: IUP_WIDGET): INTEGER
		-- Returns the number of children of the given control.
		do
			Result := int_get_child_count(control.widget)
		end

	iup_get_next_child (control: IUP_WIDGET; child: IUP_WIDGET): detachable IUP_WIDGET
		-- Returns the a child of the given control given its brother.
		-- Returns the handle of the child or Void.
		local
			p: POINTER
		do
			p := int_get_next_child(control.widget, child.widget)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_get_brother (control: IUP_WIDGET): detachable IUP_WIDGET
		-- Returns the brother of an element.
		-- Returns the brother or Void if there is none.
		local
			p: POINTER
		do
			p := int_get_brother(control.widget)

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_get_dialog (control: IUP_WIDGET): detachable IUP_DIALOG
		-- Returns the handle of the dialog that contains that interface
		-- element (or NULL if not found). Works also for children of a 
		-- menu that is associated with a dialog.
		local
			p: POINTER
		do
			p := int_get_dialog(control.widget)

			if p /= default_pointer and
				attached {IUP_DIALOG} objects.at(p) as dlg then
				Result := dlg
			end
		end

	iup_get_dialog_child (control: IUP_WIDGET; name: STRING): detachable  IUP_WIDGET
		-- Returns the identifier of the child element that has the NAME
		-- attribute equals to the given value on the same dialog 
		-- hierarchy (or void if not found). Works also for children of a 
		-- menu that is associated with a dialog.
		local
			p: POINTER
		do
			p := int_get_dialog_child(control.widget, get_pointer(name.to_c))

			if p /= default_pointer then
				Result := widget_for_object(p)
			end
		end

	iup_refresh (control: IUP_WIDGET)
		-- Updates the size and layout of all controls in the same dialog.
		do
			int_refresh(control.widget)
		end

	iup_refresh_children (control: IUP_WIDGET)
		-- Updates the size and layout of controls after changing size
		-- attributes, or attributes that affect the size of the control. 
		-- Can be used for any element inside a dialog, only its children 
		-- will be updated. It can change the layout of all the controls
		-- inside the given element because of the dynamic layout positioning.
		do
			int_refresh_children(control.widget)
		end
	
	iup_update (control: IUP_WIDGET)
		-- Mark the element to be redraw when the control returns 
		-- to the system.
		do
			int_update(control.widget)
		end

	iup_update_children (control: IUP_WIDGET)
		-- Mark element children to be redraw when the control returns 
		-- to the system.
		do
			int_update_children(control.widget)
		end

	iup_redraw (control: IUP_WIDGET; flag: INTEGER)
		-- Force the element and its children to be redrawn immediately.
		do
			int_redraw(control.widget, flag)
		end

	iup_convert_xy_to_pos(control: IUP_WIDGET; x, y: INTEGER): INTEGER
		do
			Result := int_convert_xy_to_pos(control.widget, x, y)
		end

	-- Commands to handle attributes
		
	set_attribute (wgt: IUP_WIDGET; name: STRING; value: STRING)
		do
			int_set_attribute (wgt.widget, get_pointer(name.to_c), get_pointer(value.to_c))
		end

	set_attribute_in_handle (handle: POINTER; name: STRING; value: STRING)
		do
			int_set_attribute (handle, get_pointer(name.to_c), get_pointer(value.to_c))
		end

	set_attribute_widget (wgt: IUP_WIDGET; name: STRING; other_wgt: IUP_WIDGET)
		do
			int_set_attribute_handle (wgt.widget, get_pointer(name.to_c), other_wgt.widget)
		end

	set_attribute_null (wgt: IUP_WIDGET; name: STRING)
		local
			p: POINTER
		do
			int_set_attribute (wgt.widget, get_pointer(name.to_c), p)
		end

	set_attribute_null_in_handle (wgt: POINTER; name: STRING)
		local
			p: POINTER
		do
			int_set_attribute (wgt, get_pointer(name.to_c), p)
		end

	set_str_attribute (wgt: IUP_WIDGET; name: STRING; value: STRING)
		do
			int_set_str_attribute (wgt.widget, get_pointer(name.to_c), get_pointer(value.to_c))
		end

	set_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: STRING)
		do
			int_set_attribute_id (wgt.widget, get_pointer(name.to_c), id, get_pointer(value.to_c))
		end

	set_str_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: STRING)
		do
			int_set_str_attribute_id (wgt.widget, get_pointer(name.to_c), id, get_pointer(value.to_c))
		end

	set_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: STRING)
		do
			int_set_attribute_id2 (wgt.widget, get_pointer(name.to_c), lin, col, get_pointer(value.to_c))
		end

	set_attribute_id2_null (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER)
		local
			p: POINTER
		do
			int_set_attribute_id2 (wgt.widget, get_pointer(name.to_c), lin, col, p)
		end

	set_str_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: STRING)
		do
			int_set_str_attribute_id2 (wgt.widget, get_pointer(name.to_c), lin, col, get_pointer(value.to_c))
		end

	set_int (wgt: IUP_WIDGET; name: STRING; value: INTEGER)
		do
			int_set_int (wgt.widget, get_pointer(name.to_c), value)
		end

	set_float (wgt: IUP_WIDGET; name: STRING; value: REAL_32)
		do
			int_set_float (wgt.widget, get_pointer(name.to_c), value)
		end

	set_double (wgt: IUP_WIDGET; name: STRING; value: REAL_64)
		do
			int_set_double (wgt.widget, get_pointer(name.to_c), value)
		end

	set_rgb (wgt: IUP_WIDGET; name: STRING; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb (wgt.widget, get_pointer(name.to_c), r, g, b)
		end

	set_int_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: INTEGER)
		do
			int_set_int_id (wgt.widget, get_pointer(name.to_c), id, value)
		end

	set_float_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: REAL_32)
		do
			int_set_float_id (wgt.widget, get_pointer(name.to_c), id, value)
		end

	set_double_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: REAL_64)
		do
			int_set_double_id (wgt.widget, get_pointer(name.to_c), id, value)
		end

	set_rgb_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb_id (wgt.widget, get_pointer(name.to_c), id, r, g, b)
		end

	set_int_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: INTEGER)
		do
			int_set_int_id2 (wgt.widget, get_pointer(name.to_c), lin, col, value)
		end

	set_float_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: REAL_32)
		do
			int_set_float_id2 (wgt.widget, get_pointer(name.to_c), lin, col, value)
		end

	set_double_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: REAL_64)
		do
			int_set_double_id2 (wgt.widget, get_pointer(name.to_c), lin, col, value)
		end

	set_rgb_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb_id2 (wgt.widget, get_pointer(name.to_c), lin, col, r, g, b)
		end

	reset_attribute (wgt: IUP_WIDGET; name: STRING)
		do
			int_reset_attribute (wgt.widget, get_pointer(name.to_c))
		end

	set_attribute_handle (wgt: IUP_WIDGET; name: STRING; wgt_named: IUP_WIDGET)
		do
			int_set_attribute (wgt.widget, get_pointer(name.to_c), wgt_named.widget)
		end

	get_attribute (wgt: IUP_WIDGET; name: STRING): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute (wgt.widget, get_pointer(name.to_c))

			if p /= default_pointer then
				create str.make_from_c(p)
				Result := str
			else
				Result := ""
			end
		end

	get_attribute_from_handle (handle: POINTER; name: STRING): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute (handle, get_pointer(name.to_c))
			
			if p /= default_pointer then
				create str.make_from_c(p)
				Result := str
			else
				create Result.make_empty
			end
		end

	get_attribute_widget (wgt: IUP_WIDGET; name: STRING): IUP_WIDGET
		local
			p: POINTER
		do
			p := int_get_attribute (wgt.widget, get_pointer(name.to_c))
			Result := widget_for_object(p)
		end

	get_attribute_ihandle (wgt: IUP_WIDGET; name: STRING): detachable POINTER
		local
			p: POINTER
		do
			p := int_get_attribute (wgt.widget, get_pointer(name.to_c))
			
			if p /= default_pointer then
				Result := p
			end
		end

	get_attribute_ihandle_from_handle (handle: POINTER; name: STRING): POINTER
		do
			Result := int_get_attribute (handle, get_pointer(name.to_c))
		end

	get_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute_id (wgt.widget, get_pointer(name.to_c), id)

			if p /= default_pointer then
				create str.make_from_c(p)
				Result := str
			else
				Result := ""
			end
		end

	get_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute_id2 (wgt.widget, get_pointer(name.to_c), lin, col)

			if p /= default_pointer then
				create str.make_from_c(p)
				Result := str
			else
				Result := ""
			end
		end

	get_int (wgt: IUP_WIDGET; name: STRING): INTEGER
		do
			Result := int_get_int (wgt.widget, get_pointer(name.to_c))
		end

	get_int_int (wgt: IUP_WIDGET; name: STRING; i1: POINTER; i2: POINTER): TUPLE[INTEGER, INTEGER]
		local
			a, b: STRING
			count: INTEGER
			tup: TUPLE[INTEGER, INTEGER]
		do
			count := int_get_int_int (wgt.widget, get_pointer(name.to_c), i1, i2)

			create a.make_from_c(i1)
			create b.make_from_c(i2)

			tup := [a.to_integer, b.to_integer]
			Result := tup
		end
	
	get_int2 (wgt: IUP_WIDGET; name: STRING): INTEGER
		do
			Result := int_get_int2 (wgt.widget, get_pointer(name.to_c))
		end

	get_float (wgt: IUP_WIDGET; name: STRING): REAL_32
		do
			Result := int_get_float (wgt.widget, get_pointer(name.to_c))
		end

	get_double (wgt: IUP_WIDGET; name: STRING): REAL_64
		do
			Result := int_get_double (wgt.widget, get_pointer(name.to_c))
		end

	get_rgb (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: LIST[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute(wgt, name)

			values := color.split(' ')

			if values.count.is_equal(3) and
				values.at(1).is_integer and
				values.at(2).is_integer and
				values.at(3).is_integer then
				
					tup := [values.at(1).to_integer, values.at(2).to_integer,
					        values.at(3).to_integer]
					Result := tup
			else
					io.put_string("Something goes wrong %N")
					Result := [0, 0, 0]
			end
		end

	get_rgba (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: LIST[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute(wgt, name)

			values := color.split(' ')

			if values.count.is_equal(3) and
				values.at(1).is_integer and
				values.at(2).is_integer and
				values.at(3).is_integer then
				
					tup := [values.at(1).to_integer, values.at(2).to_integer,
					        values.at(3).to_integer, 0]
					Result := tup

			elseif values.at(1).is_integer and
				values.at(2).is_integer and
				values.at(3).is_integer and
				values.at(4).is_integer then
				
				   tup := [values.at(1).to_integer, values.at(2).to_integer,
					        values.at(3).to_integer, values.at(4).to_integer]
				   Result := tup
			else
				io.put_string("Something goes wrong %N")
				Result := [0, 0, 0, 0]
			end
		end

	get_rgb_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: LIST[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute_id(wgt, name, id)

			values := color.split(' ')

			if values.count.is_equal(3) and
				values.at(1).is_integer and
				values.at(2).is_integer and
				values.at(3).is_integer then
				
					tup := [values.at(1).to_integer, values.at(2).to_integer,
					        values.at(3).to_integer]
					Result := tup
			else
				io.put_string("Something goes wrong %N")
				Result := [0, 0, 0]
			end
		end

	get_hsi (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		do
			Result := get_rgb(wgt, name)
		end

	get_hsi_real (wgt: IUP_WIDGET; name: STRING): TUPLE[REAL_64, REAL_64, REAL_64]
		local
			color: STRING
			values: LIST[STRING]
			tup: TUPLE[REAL_64, REAL_64, REAL_64]
		do
			color := get_attribute(wgt, name)

			values := color.split(' ')

			if values.count.is_equal(3) and				
				values.at(1).is_real_64 and
				values.at(2).is_real_64 and
				values.at(3).is_real_64 then
				   tup := [values.at(1).to_real_64, values.at(2).to_real_64,
					        values.at(3).to_real_64]
					Result := tup
			else
				io.put_string("Something goes wrong %N")
				Result := [(0).to_double, (0).to_double, (0).to_double]
			end
		end
	
	get_attribute_handle (wgt: IUP_WIDGET; name: STRING): IUP_WIDGET
		local
			p: POINTER	
		do
			p := int_get_attribute_handle (wgt.widget, get_pointer(name.to_c))
			Result := widget_for_object(p)
		end

feature {IUP}
	
	-- Callbacks
	
	launch_idle_action_fidle: INTEGER
		local
			v: STRING
		do
			if attached idle_action as int_cb then
				v := int_cb.item([])
				Result := return_value(v)
			end
		end

	launch_help_cb_fn (obj: POINTER)
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				iup_widget.execute_help
			end
		end

	launch_map_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_map
				Result := return_value(v)
			end
		end

	launch_unmap_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_unmap
				Result := return_value(v)
			end
		end

	launch_destroy_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_destroy
				Result := return_value(v)
			end
		end

	launch_ldestroy_cb_fn (obj: POINTER): INTEGER
		--local
		--	iup_widget: IUP_WIDGET
		do
			---if objects.has(obj) then
			--	objects.remove(obj)

			--	if objects.has(obj) then
			--		delete_widget_for_object (obj, iup_widget)
			--	end
				
				Result := return_value("IUP_DEFAULT")
			--end
		end

	launch_getfocus_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_getfocus
				Result := return_value(v)
			end
		end

	launch_killfocus_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_killfocus
				Result := return_value(v)
			end
		end

	launch_enterwindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_enterwindow
				Result := return_value(v)
			end
		end

	launch_leavewindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_leavewindow
				Result := return_value(v)
			end
		end

	launch_k_any_fni (obj: POINTER; int: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_k_any(int)
				Result := return_value(v)
			end
		end

	launch_action_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_action
				Result := return_value(v)
			end
		end

	-- Dialogs
	launch_close_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_close
				Result := return_value(v)
			end
		end

	launch_copydata_cb_fnsi (obj, cmdline: POINTER; size: INTEGER): INTEGER
		local
			v, cl: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if cmdline /= default_pointer then
					create cl.make_from_c(cmdline)
				else
					cl := ""
				end
				
				v := iup_widget.execute_copydata(cl, size)
				Result := return_value(v)
			end
		end

	-- Also for canvas, label, list.
	launch_dropfiles_cb_fnsiii (obj: POINTER; filename: POINTER; num: INTEGER; x: INTEGER; y: INTEGER): INTEGER
		local
			v, file: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				
				if filename /= default_pointer then
					create file.make_from_c(filename)
				else
					file := ""
				end
				
				v := iup_widget.execute_dropfiles(file, num, x, y)
				Result := return_value(v)
			end
		end

	launch_mdiactivate_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_mdiactivate
				Result := return_value(v)
			end
		end

	launch_move_cb_fnii (obj: POINTER; x: INTEGER; y: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_move(x, y)
				Result := return_value(v)
			end
		end

	-- Also for canvas
	launch_resize_cb_fnii (obj: POINTER; width: INTEGER; height: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_resize(width, height)
				Result := return_value(v)
			end
		end

	launch_show_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v, s: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				
				if state.is_equal(0) then
					s := "IUP_SHOW"
				elseif state.is_equal(1) then
					s := "IUP_RESTORE"
				elseif state.is_equal(2) then
					s := "IUP_MINIMIZE"
				elseif state.is_equal(3) then
					s := "IUP_MAXIMIZE"
				else
					s := "IUP_HIDE"
				end
					
				v := iup_widget.execute_show(s)
				Result := return_value(v)
			end
		end

	launch_trayclick_cb_fniii (obj: POINTER; but: INTEGER; pressed: INTEGER; dclick: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_trayclick(but, pressed, dclick)
				Result := return_value(v)
			end
		end

	-- Callback for file dialog
	launch_file_cb_fnss (obj, file_name, status: POINTER): INTEGER
		local
			v, file, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if file_name /= default_pointer then
					create file.make_from_c(file_name)
				else
					file := ""
				end

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_file(file, st)
				Result := return_value(v)
			end
		end

	-- Color update
	launch_colorupdate_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_colorupdate
				Result := return_value(v)
			end
		end

	-- Progress bar dialog
	launch_cancel_cb_fn(obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_cancel
				Result := return_value(v)
			end
		end

	-- Callbacks for tabs
	launch_tabchange_cb_fnnn (obj, new_tab, old_tab: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget and
				new_tab /= default_pointer and old_tab /= default_pointer and
				attached objects.at(new_tab) as ntab and
				attached objects.at(old_tab) as otab then
				
				v := iup_widget.execute_tabchange(ntab, otab)
				Result := return_value(v)
			end
		end

	launch_tabchangepos_cb_fnii (obj: POINTER; new_pos, old_pos: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_tabchangepos(new_pos, old_pos)
				Result := return_value(v)
			end
		end

	launch_tabclose_cb_fni (obj: POINTER; pos: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_tabclose(pos)
				Result := return_value(v)
			end
		end

	launch_rightclick_cb_fni (obj: POINTER; pos: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_rightclick(pos)
				Result := return_value(v)
			end
		end

	-- Callbacks for DetachBox
	launch_detached_cb_fnnii (obj, new_parent: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
			nparent: IUP_DIALOG
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				create nparent.dialog_widget(new_parent)

				v := iup_widget.execute_detached(nparent, x, y)
				Result := return_value(v)
			end
		end

	launch_restored_cb_fnnii (obj, old_parent: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and objects.has(old_parent) and
				attached objects.at(obj) as iup_widget and
				attached objects.at(old_parent) as oparent then

				v := iup_widget.execute_restored(oparent, x, y)
				Result := return_value(v)
			end
		end

	-- Callbacks for Expander
	launch_openclose_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_openclose(state)
				Result := return_value(v)
			end
		end

	launch_extrabutton_cb_fnii (obj: POINTER; button, pressed: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_extrabutton(button, pressed)
				Result := return_value(v)
			end
		end

	-- Callback for split, calendar, toggle, val.
	launch_valuechanged_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_valuechanged
				Result := return_value(v)
			end
		end

	-- Callback for button, label, list, text.
	launch_button_cb_fniiiis (obj: POINTER; button, pressed, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_button(button.to_character_8.out.to_integer_32,
														 pressed, x, y, st)
				Result := return_value(v)
			end
		end

	-- Callbacks for canvas
	launch_action_fnff (obj: POINTER; posx, posy: REAL_32): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_action_fnff(posx, posy)
				Result := return_value(v)
			end
		end

	launch_focus_cb_fni (obj: POINTER; focus: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_focus(focus)
				Result := return_value(v)
			end
		end

	-- Also for text.
	launch_motion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_motion(x, y, st)
				Result := return_value(v)
			end
		end

	launch_keypress_cb_fnii (obj: POINTER; c, press: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_keypress(c, press)
				Result := return_value(v)
			end
		end

	launch_scroll_cb_fniff (obj: POINTER; op: INTEGER; posx, posy: REAL_32): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_scroll(op, posx, posy)
				Result := return_value(v)
			end
		end

	launch_wheel_cb_fndiis (obj: POINTER; delta: REAL_32; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_wheel(delta, x, y, st)
				Result := return_value(v)
			end
		end

	-- Callback for link
	launch_click_cb_fns (obj, url: POINTER): INTEGER
		local
			v, u: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if url /= default_pointer then
					create u.make_from_c(url)
				else
					u := ""
				end
				
				v := iup_widget.execute_click(u)
				Result := return_value(v)
			end
		end

	-- Callbacks for list

	launch_action_fnsii (obj, text: POINTER; item, state: INTEGER): INTEGER
		local
			v, t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if text /= default_pointer then
					create t.make_from_c(text)
				else
					t := ""
				end
				
				v := iup_widget.execute_action_fnsii(t, item, state)
				Result := return_value(v)
			end
		end

	launch_caret_cb_fniii (obj: POINTER; lin, col, pos: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_caret(lin, col, pos)
				Result := return_value(v)
			end
		end

	launch_dblclick_cb_fnis (obj: POINTER; item: INTEGER; text: POINTER): INTEGER
		local
			v, t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if text /= default_pointer then
					create t.make_from_c(text)
				else
					t := ""
				end
				
				v := iup_widget.execute_dblclick(item, t)
				Result := return_value(v)
			end
		end

	launch_dragdrop_cb_fniiii (obj: POINTER; drag_id, drop_id, isshift, iscontrol: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dragdrop(drag_id, drop_id, isshift, iscontrol)
				Result := return_value(v)
			end
		end

	launch_dropdown_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dropdown(state)
				Result := return_value(v)
			end
		end

	launch_edit_cb_fnis (obj: POINTER; c: INTEGER; new_value: POINTER): INTEGER
		local
			v, nv: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if new_value /= default_pointer then
					create nv.make_from_c(new_value)
				else
					nv := ""
				end
				
				v := iup_widget.execute_edit(c, nv)
				Result := return_value(v)
			end
		end

	launch_multiselect_cb_fns (obj, value: POINTER): INTEGER
		local
			v, tv: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if value /= default_pointer then
					create tv.make_from_c(value)
				else
					tv := ""
				end
				
				v := iup_widget.execute_multiselect(tv)
				Result := return_value(v)
			end
		end

	-- Callback for spin.
	launch_spin_cb_fni (obj: POINTER; inc: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_spin(inc)
				Result := return_value(v)
			end
		end

	-- Callbacks for text.
	launch_action_fnis (obj: POINTER; c: INTEGER; new_value: POINTER): INTEGER
		local
			v, nv: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if new_value /= default_pointer then
					create nv.make_from_c(new_value)
				else
					nv := ""
				end
				
				v := iup_widget.execute_action_fnis(c, nv)
				Result := return_value(v)
			end
		end

	-- Callbacks for toggle.
	launch_action_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_action_fni(state)
				Result := return_value(v)
			end
		end

	-- Callbacks for tree
	launch_selection_cb_fnii (obj: POINTER; id, status: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_selection(id, status)
				Result := return_value(v)
			end
		end

	launch_multiselection_cb_fnpi (obj: POINTER; ids: POINTER; n: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_multiselection(ids, n)
				Result := return_value(v)
			end
		end

	launch_multiunselection_cb_fnpi (obj: POINTER; ids: POINTER; n: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_multiunselection(ids, n)
				Result := return_value(v)
			end
		end

	launch_branchopen_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_branchopen(id)
				Result := return_value(v)
			end
		end

	launch_branchclose_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_branchclose(id)
				Result := return_value(v)
			end
		end

	launch_executeleaf_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_executeleaf(id)
				Result := return_value(v)
			end
		end

	launch_showrename_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_showrename(id)
				Result := return_value(v)
			end
		end

	launch_rename_cb_fnis (obj: POINTER; id: INTEGER; title: POINTER): INTEGER
		local
			v, t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if title /= default_pointer then
					create t.make_from_c(title)
				else
					t := ""
				end
				
				v := iup_widget.execute_rename(id, t)
				Result := return_value(v)
			end
		end

	launch_noderemoved_cb_fns (obj: POINTER; userdata: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_noderemoved(userdata)
				Result := return_value(v)
			end
		end

	launch_togglevalue_cb_fnii (obj: POINTER; id, state: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_togglevalue(id, state)
				Result := return_value(v)
			end
		end

	-- Callback for menu item ans submenu
	launch_highlight_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_highlight
				Result := return_value(v)
			end
		end

	-- Callbacks for menus
	launch_open_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_open
				Result := return_value(v)
			end
		end

	launch_menuclose_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_menuclose
				Result := return_value(v)
			end
		end

	-- Drag&Drop callbacks
	launch_dragbegin_cb_fnii (obj: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dragbegin(x, y)
				Result := return_value(v)
			end
		end

	launch_dragdatasize_cb_fns (obj, type: POINTER): INTEGER
		local
			t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if type /= default_pointer then
					create t.make_from_c(type)
				else
					t := ""
				end
				
				Result := iup_widget.execute_dragdatasize(t)
			end
		end

	launch_dragdata_cb_fnsvi (obj, type, data: POINTER; size: INTEGER): INTEGER
		local
			v, t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if type /= default_pointer then
					create t.make_from_c(type)
				else
					t := ""
				end
				
				v := iup_widget.execute_dragdata(t, data, size)
				Result := return_value(v)
			end
		end

	launch_dragend_cb_fni (obj: POINTER; action: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dragend(action)
				Result := return_value(v)
			end
		end

	launch_dropdata_cb_fnsviii (obj, type, data: POINTER; size, x, y: INTEGER): INTEGER
		local
			v, t: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if type /= default_pointer then
					create t.make_from_c(type)
				else
					t := ""
				end
				
				v := iup_widget.execute_dropdata(t, data, size, x, y)
				Result := return_value(v)
			end
		end

	launch_dropmotion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_dropmotion(x, y, st)
				Result := return_value(v)
			end
		end

	-- Callback for recent file menu

	launch_recent_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_recent
				Result := return_value(v)
			end
		end

	-- Callback for get param

	launch_param_cb_fniv (obj: POINTER; param_index: INTEGER; user_data: POINTER): INTEGER
		do
			if attached get_param as int_cb then
				Result := int_cb.execute_param(obj, param_index, user_data)
			end
		end

	-- Callbacks for flat button

	launch_flat_action_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_flat_action
				Result := return_value(v)
			end
		end

	launch_flat_button_cb_fniiiis (obj: POINTER; button, pressed, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end

				v := iup_widget.execute_flat_button(button.to_character_8.out.to_integer_32,
																pressed, x, y, st)
				Result := return_value(v)
			end
		end

	launch_flat_focus_cb_fni (obj: POINTER; focus: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_flat_focus(focus)
				Result := return_value(v)
			end
		end

	launch_flat_enterwindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_flat_enterwindow
				Result := return_value(v)
			end
		end

	launch_flat_leavewindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_flat_leavewindow
				Result := return_value(v)
			end
		end

	-- Callbacks for cells
	
	launch_draw_cb_fniiiiiic (obj: POINTER; line, column, xmin, xmax, ymin, ymax: INTEGER; canvas: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_draw(line, column, xmin, xmax, ymin, ymax, canvas)
				Result := return_value(v)
			end
		end
	
	launch_height_cb_fni (obj: POINTER; line: INTEGER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_height(line)
			end
		end
			
	launch_hspan_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_hspan(line, column)
			end
		end

	launch_mouseclick_cb_fniiiiiis (obj: POINTER; button, pressed, line, column, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_mouseclick(button.to_character_8.out.to_integer_32,
															  pressed, line, column, x, y, st)
				Result := return_value(v)
			end
		end
		
	launch_mousemotion_cb_fniiiis (obj: POINTER; line, column, x, y: INTEGER; r: POINTER): INTEGER
		local
			v, rs: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if r /= default_pointer then
					create rs.make_from_c(r)
				else
					rs := ""
				end
				
				v := iup_widget.execute_mousemotion(line, column, x, y, rs)
				Result := return_value(v)
			end
		end

	launch_ncols_cb_fn (obj: POINTER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_ncols
			end
		end
	
	launch_nlines_cb_fn (obj: POINTER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_nlines
			end
		end
	
	launch_scrolling_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_scrolling(line, column)
				Result := return_value(v)
			end
		end

	launch_vspan_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_vspan(line, column)
			end
		end
	
	launch_width_cb_fni (obj: POINTER; column: INTEGER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_width(column)
			end
		end

	-- Callbacks for color bar

	launch_cell_fni (obj: POINTER; cell: INTEGER): INTEGER
		local
			cl: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				cl := iup_widget.execute_cell(cell)

				if cl /= Void then
					Result := int_encode_color (cl.integer_32_item(1),
														 cl.integer_32_item(2),
														 cl.integer_32_item(3))	
				else
					Result := -1
				end
			end
		end

	launch_extended_fni (obj: POINTER; cell: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_extended(cell)
				Result := return_value(v)
			end
		end

	launch_select_fnii (obj: POINTER; cell, type: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_select(cell, type)
				Result := return_value(v)
			end
		end

	launch_switch_fnii (obj: POINTER; prim_cell, sec_cell: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_switch(prim_cell, sec_cell)
				Result := return_value(v)
			end
		end

	-- Callbacks for Matrix

	launch_action_fniiiis (obj: POINTER; key, lin, col, edition: INTEGER; value: POINTER): INTEGER
		local
			v, vs: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if value /= default_pointer then
					create vs.make_from_c(value)
				else
					vs := ""
				end
				
				v := iup_widget.execute_action_fniiiis(key, lin, col, edition, vs)
				Result := return_value(v)
			end
		end

	launch_click_fniis (obj: POINTER; lin, col: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_click_fniis(lin, col, st)
				Result := return_value(v)
			end
		end

	launch_colresize_fni (obj: POINTER; col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_colresize(col)
				Result := return_value(v)
			end
		end

	launch_release_fniis (obj: POINTER; lin, col: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_release(lin, col, st)
				Result := return_value(v)
			end
		end

	launch_resizematrix_fnii (obj: POINTER; width, height: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_resizematrix(width, height)
				Result := return_value(v)
			end
		end

	launch_mousemove_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_mousemove(lin, col)
				Result := return_value(v)
			end
		end

	launch_enteritem_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_enteritem(lin, col)
				Result := return_value(v)
			end
		end

	launch_leaveitem_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_leaveitem(lin, col)
				Result := return_value(v)
			end
		end

	launch_scrolltop_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_scrolltop(lin, col)
				Result := return_value(v)
			end
		end

	launch_bgcolor_fniivvv (obj: POINTER; lin, col: INTEGER; red, green, blue: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_bgcolor(lin, col, red, green, blue)
				Result := return_value(v)
			end
		end

	launch_fgcolor_fniivvv (obj: POINTER; lin, col: INTEGER; red, green, blue: POINTER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_fgcolor(lin, col, red, green, blue)
				Result := return_value(v)
			end
		end

	launch_font_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := get_pointer(iup_widget.execute_font(lin, col).to_c)
			end
		end

	launch_type_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := get_pointer(iup_widget.execute_type(lin, col).to_c)
			end
		end

	launch_dropcheck_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dropcheck(lin, col)
				Result := return_value(v)
			end
		end

	launch_translatevalue_fniis (obj: POINTER; lin, col: INTEGER; value: POINTER): POINTER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if value /= default_pointer then
					create v.make_from_c(value)
				else
					v := ""
				end
				
				Result := get_pointer(iup_widget.execute_translatevalue(lin, col, v).to_c)
			end
		end
	
	launch_togglevalue_fniii (obj: POINTER; lin, col, status: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_togglevalue_fniii(lin, col, status)
				Result := return_value(v)
			end
		end

	launch_drop_fnnii (obj, drop: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_drop: IUP_DROP
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if objects.has(drop) and
					attached {IUP_DROP} objects.at(drop) as iup_d then
						-- All Ok
						iup_drop := iup_d
				else
					create iup_drop.drop_widget(drop)
				end
				
				v := iup_widget.execute_drop(iup_drop, lin, col)
				Result := return_value(v)
			end
		end

	launch_menudrop_fnnii (obj, drop: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_drop: IUP_DROP
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if objects.has(drop) and
					attached {IUP_DROP} objects.at(drop) as iup_d then
						-- All Ok
						iup_drop := iup_d
				else
					create iup_drop.drop_widget(drop)
				end
				
				v := iup_widget.execute_menudrop(iup_drop, lin, col)
				Result := return_value(v)
			end
		end

	launch_dropselect_fniinsii (obj: POINTER; lin, col: INTEGER; drop, t: POINTER; i, v: INTEGER): INTEGER
		local
			r, ts: STRING
			iup_drop: IUP_DROP
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if t /= default_pointer then
					create ts.make_from_c(t)
				else
					ts := ""
				end

				if objects.has(drop) and
					attached {IUP_DROP} objects.at(drop) as iup_d then
						-- All OK
						iup_drop := iup_d
				else
					create iup_drop.drop_widget(drop)
				end
				
				r := iup_widget.execute_dropselect(lin, col, iup_drop, ts, i, v)
				Result := return_value(r)
			end
		end

	launch_edition_fniiii (obj: POINTER; lin, col, mode, update: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_edition(lin, col, mode, update)
				Result := return_value(v)
			end
		end

	launch_value_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		local
			s: STRING
			cs: C_STRING
		do
			--s := "hola"
			--create cs.make_by_pointer(get_pointer(s.to_c))
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				s := iup_widget.execute_value(lin, col)
				--create cs.make_by_pointer(get_pointer((iup_widget.execute_value(lin, 
				--col)).to_c))
				create cs.make_by_pointer(get_pointer(s.to_c))
				Result := cs.item
			end
		end

	launch_value_edit_fniis (obj: POINTER; lin, col: INTEGER; newval: POINTER): INTEGER
		local
			v, nv: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if newval /= default_pointer then
					create nv.make_from_c(newval)
				else
					nv := ""
				end
				
				v := iup_widget.execute_value_edit(lin, col, nv)
				Result := return_value(v)
			end
		end

	launch_mark_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				Result := iup_widget.execute_mark(lin, col)
			end
		end

	launch_markedit_fniii (obj: POINTER; lin, col, marked: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_markedit(lin, col, marked)
				Result := return_value(v)
			end
		end

	-- Flat tabs
	launch_flat_motion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then

				if status /= default_pointer then
					create st.make_from_c(status)
				else
					st := ""
				end
				
				v := iup_widget.execute_flat_motion(x, y, st)
				Result := return_value(v)
			end
		end

	-- Drop button

	launch_dropshow_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_dropshow(state)
				Result := return_value(v)
			end
		end

	-- Dial

	launch_button_press_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_button_press(angle)
				Result := return_value(v)
			end
		end

	launch_button_release_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_button_release(angle)
				Result := return_value(v)
			end
		end

	launch_mousemove_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_mousemove_fnd(angle)
				Result := return_value(v)
			end
		end

	-- Color browser

	launch_change_cb_fnvvv (obj: POINTER; red, green, blue: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_change(red, green, blue)
				Result := return_value(v)
			end
		end

	launch_drag_cb_fnvvv (obj: POINTER; red, green, blue: INTEGER): INTEGER
		local
			v: STRING
		do
			if objects.has(obj) and
				attached objects.at(obj) as iup_widget then
				v := iup_widget.execute_drag(red, green, blue)
				Result := return_value(v)
			end
		end

feature {IUP_DIALOG}

	get_drop_button_for_dialog (dlg: IUP_DIALOG): detachable IUP_DROP_BUTTON
		local
			p: POINTER
		do
			p := get_attribute_ihandle(dlg, "DROPBUTTON")
			
			if objects.has(p) and
				attached {IUP_DROP_BUTTON} objects.at(p) as iup_drop_button then
				-- All Ok
				Result := iup_drop_button
			end
		end

feature {IUP_WIDGET, IUP_CLIPBOARD}

	-- Validations

	is_valid_position (x, y: STRING): BOOLEAN
		local
			xs, ys: BOOLEAN
		do
			if x.is_equal("IUP_LEFT") or
				x.is_equal("IUP_CENTER") or
				x.is_equal("IUP_RIGHT") or
				x.is_equal("IUP_MOUSEPOS") or
				x.is_equal("IUP_CENTERPARENT") or
				x.is_equal("IUP_CURRENT") then
				xs := True
			elseif x.is_integer and x.to_integer >= 0 then
				xs := True
			else
				xs := False
			end

			if y.is_equal("IUP_TOP") or
				y.is_equal("IUP_CENTER") or
				y.is_equal("IUP_BOTTOM") or
				y.is_equal("IUP_MOUSEPOS") or
				y.is_equal("IUP_CENTERPARENT") or
				y.is_equal("IUP_CURRENT") then
				ys := True
			elseif y.is_integer and y.to_integer >= 0 then
				ys := True
			else
				ys := False
			end

			if xs and ys then
				Result := True
			else
				Result := False
			end
		end

	is_valid_buttons (value: STRING): BOOLEAN
		do
			if value.is_equal("OK") or
				value.is_equal("OKCANCEL") or
				value.is_equal("RETRYCANCEL") or
				value.is_equal("YESNO") or
				value.is_equal("YESNOCANCEL") then
				Result := True
			else
				Result := False
			end
		end	

feature {NONE}

	idle_action: detachable FUNCTION[TUPLE, STRING]
	objects:     HASH_TABLE[IUP_WIDGET, POINTER]
	callbacks:   detachable HASH_TABLE[IUP_WIDGET, POINTER]

	get_param: detachable IUP_GET_PARAM

	-- Conversion

	yesno_to_boolean (value: STRING): BOOLEAN
		do
			if value.is_equal("YES") then
				Result := True
			else
				Result := False
			end
		end

	boolean_to_yesno (value: BOOLEAN): STRING
		do
			if value then
				Result := "YES"
			else
				Result := "NO"
			end
		end

	components_of (size: STRING; separator: CHARACTER): TUPLE[INTEGER, INTEGER]
		local
			i, c: INTEGER
			width, height: STRING
			tup: TUPLE[INTEGER, INTEGER]
		do
			if size.has(separator) then
				i := size.index_of(separator, 1)
				c := size.count
				
				if not i.is_equal(1) then
					width := size.substring(1, i - 1)
				else
					width := "0"
				end
				
				if not i.is_equal(c) then
					height := size.substring(i + 1, c)
				else
					height := "0"
				end

				tup := [width.to_integer, height.to_integer]
				Result := tup
			else
				io.put_string("Unable to get the components %N")
				Result := [0, 0]
			end
		end

	convert_string_to_array (data: STRING): POINTER
		local
			v: CHARACTER
			arg: MANAGED_POINTER
			x: INTEGER
		do
			create arg.make(data.count)
			
			from
				x := 1
         until
				x = data.count
         loop
				v := data.item(x)
				arg.put_character(v.to_character_8, x - 1)
				x := x + 1
         end
			
			Result := arg.item
		end

	-- Class name

	get_class_name (wgt: POINTER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_class_name (wgt)
			
			if p /= default_pointer then
				create str.make_from_c(p)
				Result := str
			else
				Result := ""
			end
		end

	int_get_class_name (wgt: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetClassName ($wgt);"
      end
	
	-- Loop

	int_loop_step: INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupLoopStep();"
      end

	int_loop_step_wait: INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupLoopStepWait();"
      end

	-- PopUp

	int_popup (wgt: POINTER; x, y: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupPopup ($wgt, $x, $y);"
      end

	-- Help

	int_help (u: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupHelp ($u);"
      end
	
	-- Global attributes
	
	int_set_global (name: POINTER; value: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetGlobal ($name, $value)"
      end

	int_get_global (name: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetGlobal ($name)"
      end

	-- Focus

	int_get_focus: POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetFocus();"
		end

	-- Destroy
	int_destroy (wgt: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupDestroy ($wgt);"
      end

	-- Callbacks

	widget_for_object (wgt: POINTER): IUP_WIDGET
		do
			if objects.has(wgt) and
				attached objects.at(wgt) as w then
				Result := w
			else
				create Result.make
			end
		end
	
	return_value (type: STRING): INTEGER
		do
			if type /= Void then
				if (type.is_equal("IUP_IGNORE")) then
					Result := -1
				elseif (type.is_equal("IUP_DEFAULT")) then
					Result := -2
				elseif (type.is_equal("IUP_CLOSE")) then
					Result := -3
				elseif (type.is_equal("IUP_CONTINUE")) then
					Result := -4
				else
					Result := -1
				end
			else
				Result := -1
			end
		end

	int_set_callback (object: POINTER; name: POINTER; type: POINTER; operation: INTEGER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"connect_callback ($object, $name, $type, $operation);"
      end

	int_set_function (object: POINTER; operation: INTEGER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"connect_function ($object, $operation);"
      end

	-- Hierarchy and management.
	
	int_append (control: POINTER; new_child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupAppend ($control, $new_child);"
      end

	int_detach (control: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupDetach ($control);"
      end
	
	int_insert (control: POINTER; ref_child: POINTER; new_child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupInsert ($control, $ref_child, $new_child);"
      end

	int_reparent (child: POINTER; new_parent: POINTER; ref_child: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupReparent ($child, $new_parent, $ref_child);"
      end

	int_get_parent (child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetParent ($child);"
      end

	int_get_child (control: POINTER; position: INTEGER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetChild ($control, $position);"
      end

	int_get_child_pos (control: POINTER; child: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetChildPos ($control, $child);"
      end

	int_get_child_count (control: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetChildCount ($control);"
      end

	int_get_next_child (control: POINTER; child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetNextChild ($control, $child);"
      end

	int_get_brother (control: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetBrother ($control);"
      end

	int_get_dialog (control: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetDialog ($control);"
      end

	int_get_dialog_child (control: POINTER; child: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetDialogChild ($control, $child);"
      end

	int_refresh (control: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupRefresh ($control);"
      end

	int_refresh_children (control: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupRefreshChildren ($control);"
      end

	int_update (control: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupUpdate ($control);"
      end

	int_update_children (control: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupUpdateChildren ($control);"
      end

	int_redraw (control: POINTER; ch: INTEGER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupRedraw ($control, $ch);"
      end

	int_convert_xy_to_pos (control: POINTER; x, y: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupConvertXYToPos ($control, $x, $y);"
      end
	
	-- Attributes
	
   int_set_attribute (wgt: POINTER; name: POINTER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetAttribute ($wgt, $name, $value);"
      end

   int_set_str_attribute (wgt: POINTER; name: POINTER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetStrAttribute ($wgt, $name, $value);"
      end

	int_set_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetAttributeId ($wgt, $name, $id, $value);"
      end

   int_set_str_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetStrAttributeId ($wgt, $name, $id, $value);"
      end

	int_set_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetAttributeId2 ($wgt, $name, $lin, $col, $value);"
      end

   int_set_str_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetStrAttributeId2 ($wgt, $name, $lin, $col, $value);"
      end

	int_set_int (wgt: POINTER; name: POINTER; value: INTEGER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetInt ($wgt, $name, $value);"
      end

	int_set_float (wgt: POINTER; name: POINTER; value: REAL_32)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetFloat ($wgt, $name, $value);"
      end

	int_set_double (wgt: POINTER; name: POINTER; value: REAL_64)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetDouble ($wgt, $name, $value);"
      end

	int_set_rgb (wgt: POINTER; name: POINTER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetRGB ($wgt, $name, $r, $g, $b);"
      end

	int_set_int_id (wgt: POINTER; name: POINTER; id: INTEGER; value: INTEGER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetIntId ($wgt, $name, $id, $value);"
      end

	int_set_float_id (wgt: POINTER; name: POINTER; id: INTEGER; value: REAL_32)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetFloatId ($wgt, $name, $id, $value);"
      end

	int_set_double_id (wgt: POINTER; name: POINTER; id: INTEGER; value: REAL_64)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetDoubleId ($wgt, $name, $id, $value);"
      end

	int_set_rgb_id (wgt: POINTER; name: POINTER; id: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetRGBId ($wgt, $name, $id, $r, $g, $b);"
      end

	int_set_int_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: INTEGER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetIntId2 ($wgt, $name, $lin, $col, $value);"
      end

	int_set_float_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: REAL_32)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetFloatId2 ($wgt, $name, $lin, $col, $value);"
      end

	int_set_double_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: REAL_64)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetDoubleId2 ($wgt, $name, $lin, $col, $value);"
      end

	int_set_rgb_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetRGBId2 ($wgt, $name, $lin, $col, $r, $g, $b);"
      end

	int_reset_attribute (wgt: POINTER; name: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupResetAttribute ($wgt, $name);"
      end

	int_set_attribute_handle (wgt: POINTER; name: POINTER; wgt_named: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetAttributeHandle ($wgt, $name, $wgt_named);"
      end

	int_get_attribute (wgt: POINTER; name: POINTER): POINTER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetAttribute ($wgt, $name);"
      end

	int_get_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER): POINTER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetAttributeId ($wgt, $name, $id);"
      end

	int_get_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER): POINTER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetAttributeId2 ($wgt, $name, $lin, $col);"
      end

	int_get_int (wgt: POINTER; name: POINTER): INTEGER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetInt ($wgt, $name);"
      end

	int_get_int_int (wgt: POINTER; name: POINTER; i1: POINTER; i2: POINTER): INTEGER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetIntInt ($wgt, $name, $i1, $i2);"
      end

	int_get_int2 (wgt: POINTER; name: POINTER): INTEGER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetInt2 ($wgt, $name);"
      end

	int_get_float (wgt: POINTER; name: POINTER): REAL_32
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetFloat ($wgt, $name);"
      end

	int_get_double (wgt: POINTER; name: POINTER): REAL_64
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetDouble ($wgt, $name);"
      end

	int_get_rgb (wgt: POINTER; name, r, g, b: POINTER)
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupGetRGB ($wgt, $name, $r, $g, $b);"
      end

	int_get_attribute_handle (wgt: POINTER; name: POINTER): POINTER
      external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetAttributeHandle ($wgt, $name);"
      end

	-- Key codes

	int_is_print_key(key: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isprint ($key);"
      end

	int_is_x_key(key: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isXkey ($key);"
      end
	
	int_is_shift_x_key(key: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isShiftXkey ($key);"
      end

	int_is_ctrl_x_key(key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isCtrlXkey ($key);"
      end

	int_is_alt_x_key(key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isAltXkey ($key);"
      end

	int_is_sys_x_key(key: CHARACTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isSysXkey ($key);"
      end

	-- Mouse buttons

	int_is_shift(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isshift (((char *) $status));"
      end

	int_is_control(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_iscontrol (((char *) $status));"
      end

	int_is_button_1(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isbutton1 (((char *) $status));"
      end

	int_is_button_2(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isbutton2 (((char *) $status));"
      end

	int_is_button_3(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isbutton3 (((char *) $status));"
      end

	int_is_button_4(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isbutton4 (((char *) $status));"
      end

	int_is_button_5(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isbutton5 (((char *) $status));"
      end

	int_is_double(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isdouble (((char *) $status));"
      end

	int_is_alt(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_isalt (((char *) $status));"
      end

	int_is_sys(status: POINTER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return iup_issys (((char *) $status));"
      end

	-- CD

	int_use_context_plus(status: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return cdUseContextPlus ($status);"
      end

	int_encode_color (r, g, b: INTEGER): INTEGER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return cdEncodeColor ($r, $g, $b);"
      end

	-- Languages

	int_set_language_string (n, v: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetLanguageString ($n, $v);"
		end

	int_store_language_string (n, v: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupStoreLanguageString ($n, $v);"
		end

	int_get_language_string (n: POINTER): POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupGetLanguageString($n);"
		end

	int_set_language_pack (p: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupSetLanguagePack ($p);"
		end

	-- Copy attributes

	int_copy_attributes (s, d: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"IupCopyAttributes ($s, $d);"
		end

	-- IUP Callbacks

	set_iup_callbacks (obj,
					       l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19,
							 l20, l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36, l37, l38, l39,
							 l40, l41, l42, l43, l44, l45, l46, l47, l48, l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59,
							 l60, l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72, l73, l74, l75, l76, l77, l78, l79,
							 l80, l81, l82, l83, l84, l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96, l97, l98, l99,
							 l100, l101, l102, l103, l104, l105, l106, l107, l108, l109, l110, l111, l112, l113, l114, l115, l116, l117, l118, l119,
							 l120, l121: POINTER)
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"set_callbacks ($obj,%
					       %$l1, $l2, $l3, $l4, $l5, $l6, $l7, $l8, $l9, $l10, $l11, $l12, $l13, $l14, $l15, $l16, $l17, $l18, $l19,%
							 %$l20, $l21, $l22, $l23, $l24, $l25, $l26, $l27, $l28, $l29, $l30, $l31, $l32, $l33, $l34, $l35, $l36, $l37, $l38, $l39,%
							 %$l40, $l41, $l42, $l43, $l44, $l45, $l46, $l47, $l48, $l49, $l50, $l51, $l52, $l53, $l54, $l55, $l56, $l57, $l58, $l59,%
							 %$l60, $l61, $l62, $l63, $l64, $l65, $l66, $l67, $l68, $l69, $l70, $l71, $l72, $l73, $l74, $l75, $l76, $l77, $l78, $l79,%
							 %$l80, $l81, $l82, $l83, $l84, $l85, $l86, $l87, $l88, $l89, $l90, $l91, $l92, $l93, $l94, $l95, $l96, $l97, $l98, $l99,%
							 %$l100, $l101, $l102, $l103, $l104, $l105, $l106, $l107, $l108, $l109, $l110, $l111, $l112, $l113, $l114, $l115, $l116, $l117, $l118, $l119,%
							 %$l120, $l121);"
		end

end -- class IUP

-- The MIT License (MIT)

-- Copyright (c) 2016, 2017, 2018, 2019, 2020 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
